package start.demo01.email;

import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;
import com.sun.mail.imap.IdleManager;

import java.text.SimpleDateFormat;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.event.MessageChangedEvent;
import javax.mail.event.MessageCountAdapter;
import javax.mail.event.MessageCountEvent;

import org.junit.Test;

public class ListenMail {


    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
    private static final Properties PROPS = System.getProperties();

    //    配置项	    SMTP	POP3	IMAP
    //    普通方式	25	    110	    143
    //    SSL方式	465	    995	    993
    static {
        PROPS.setProperty("mail.imap.auth", "true");
        PROPS.setProperty("mail.store.protocol", "imap");
        PROPS.setProperty("mail.imap.ssl.enable", "true");
        PROPS.setProperty("mail.imap.auth.login.disable", "true");
        PROPS.setProperty("mail.imap.usesocketchannels", "true");
    }

    private IMAPFolder folder;
    private IMAPStore store;
    private IdleManager idleManager;

    private void openStore() throws Exception {
        Session session = Session.getInstance(PROPS, null);
        ExecutorService es = Executors.newCachedThreadPool();
        this.idleManager = new IdleManager(session, es);
        // 2、通过session得到Store对象
        this.store = (IMAPStore) session.getStore("imap");
        // 3、连上邮件服务器
        store.connect("imap.qq.com", 993, "790867216@qq.com", "khmkygxoiexvbfgf");
    }

    private void openFolder() {
        try {
            openStore();
            this.folder = (IMAPFolder) this.store.getFolder("INBOX");
            if (folder == null) {
                throw new Exception("No IMAP INBOX");
            }
            System.out.println("启动时间：" + sdf.format(System.currentTimeMillis()));
            this.folder.open(Folder.READ_WRITE);
            this.folder.addMessageCountListener(
                    new MessageCountAdapter() {
                        public void messagesAdded(MessageCountEvent ev) {
                            System.out.println("addMessageCountListener");
                            Message[] msgs = ev.getMessages();
                            try {
                                for (Message msg : msgs) {
                                    System.out.println(sdf.format(System.currentTimeMillis()) + "get new msg：" + msg.getSubject());
                                    idleManager.watch(folder);
                                }
                            } catch (MessagingException e) {
                                e.printStackTrace();
                            }
                        }
                    });
            this.folder.addMessageChangedListener((MessageChangedEvent e)->{
                Message message = e.getMessage();
                try {
                    System.out.println("消息改变监听"+message.getSubject());
                } catch (MessagingException ex) {
                    ex.printStackTrace();
                }
            });
            idleManager.watch(folder);
            // log.info("开始走判断folder.idle");
            // ThreadUtil.execAsync(
            //     () -> {
            //       try {
            //         while (true) {
            //           log.info("来了idle---------------------");
            //           folder.idle();
            //         }
            //       } catch (MessagingException e) {
            //         e.printStackTrace();
            //       }
            //     });
            // 中断后继续idle
            // for (; ; ) {
            //   try {
            //     log.info("开始走判断folder.idle，进来了1");
            //     if (!folder.isOpen()) {
            //       log.warn("idle -------------------- 重新打开folder");
            //       folder.open(Folder.READ_WRITE);
            //     }
            //     log.info("开始走判断folder.idle，进来了2");
            //     if (folder instanceof IMAPFolder) {
            //       IMAPFolder f = (IMAPFolder) folder;
            //       log.info("开始走判断folder.idle，进来了2.1，支持idle");
            //       f.idle();
            //     } else {
            //       log.info("开始走判断folder.idle，进来了2.2，不支持idle");
            //       folder.getMessageCount();
            //     }
            //     log.info("开始走判断folder.idle，进来了3");
            //     log.info("idle -------------------- 邮件活动。。。");
            //   } catch (FolderClosedException e) {
            //     log.error("异常:FolderClosedException,", e);
            //   }
            // }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void worker() {
        try {
            while (true) {
                Thread.sleep(5000);
                System.out.println("work-->：" + this.folder.getMessageCount());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void noop() throws InterruptedException {
        Thread.sleep(5000);
//        log.info("定时通信,保持邮箱连接有效,time:{}", sdf.format(System.currentTimeMillis()));
        System.out.println("定时通信,保持邮箱连接有效,time:"+sdf.format(System.currentTimeMillis()));
        if (folder == null) {
            System.out.println("初始化mail 连接");
            openFolder();
        }
        System.out.println("发送NOOP 命令");
        try {
            Object val =
                    folder.doCommand(p -> {
                        p.simpleCommand("NOOP", null);
                        return null;
                    });
        } catch (MessagingException e) {
            System.out.println("NOOP 异常");
            e.printStackTrace();
        }
        System.out.println("发送NOOP 命令 done!");
    }

    @Test
    public void main() throws InterruptedException {
        ListenMail mail2 = new ListenMail();
        mail2.openFolder();

//        mail2.noop();
        mail2.worker();
    }
}
